import {h} from "vue"
import { IPackNifi } from "src/inter";
import Nifi from "../../nifi";
import { Cell, Node } from "pack-antv-x6"
import markup from "./markup";
import ContextmenuElem from "./contextmenu.vue"
import { DEFAULT_CELL_NAME, DEFAULT_NODE_PORTS } from "../metadata";
import { pickData, diff } from "../../util"
import { t } from "../../i18n/index"

const KEYS: [key: string, sk?: any][] = [
    ['id'],
    // ['label', 'component.name'],
    ['label', 'component.label'],
    ['value', 'component.label'],
    ["position.x", "position.x"],
    ["position.y", "position.y"],
    ['version', 'revision.version']
];

const name = DEFAULT_CELL_NAME.labels.en;
const shape = `node-${name}`;
//
export default (nifi: Nifi): IPackNifi.ModuleFunnels => {
    //
    nifi.graph.registerNode(shape, markup)
    //
    nifi.graph.onMounted((graph) => {
        // labels 事件
        let labelNode: Node | undefined = undefined;
        let labelNodePos = [0, 0, 0, 0]
        graph.on("labels:resize", (arg: any) => {
            const { e, node } = arg;
            e.preventDefault();
            e.stopPropagation();
            const size = node.size();
            const { localX, localY } = nifi.mousepos.eventPos(e as any)
            labelNodePos = [localX, localY, size.width, size.height]
            labelNode = node;
        })
        nifi.graph.boxEl.addEventListener('mouseup', () => {
            labelNode && updateSize(labelNode), labelNode = undefined
        })
        nifi.graph.boxEl.addEventListener('mousemove', (e) => {
            if (labelNode) {
                const { localX, localY } = nifi.mousepos.eventPos(e as any)
                const width = localX - labelNodePos[0] + labelNodePos[2]
                const height = localY - labelNodePos[1] + labelNodePos[3]
                //
                labelNode.resize(width, height)
            }
        })
    })
    //
    const init = (tds: any[]) => {
        const res: any[] = [];
        for (const td of new Array().concat(tds)) {
            if (!td) continue;
            nifi.cells.set(td)
            const md: any = { ...pickData(td, KEYS), name, shape };
            res.push(md)
        }
        return res;
    }

    const updateSize = async (node: Node) => {
        const size = node.size();
        const sd = nifi.cells.get(node)
        const data = { revision: sd.revision, disconnectedNodeAcknowledged: false, component: { id: node.id, ...size } }
        const td = await nifi.cells.setCell(node, data)
        update(td)
    }

    const hookCall = (sd: any, id: string) => {
        // const se = nifi.graph.getCellById(sd.id)
        // console.log('....',id,se)
        // if(se){
        //     const status = se.prop('status')
        //     nifi.graph.getCellById(id)?.prop({status})
        //     nifi.cells.connections.updateStatus(id);
        // }

    }

    // 新增元素
    const add = async (d: any) => {
        const data = { component: { position: d.position }, disconnectedNodeAcknowledged: false, revision: { clientId: nifi.flow.clientId, version: 0 } }
        //
        const td = await nifi.cells.addCell(name, data)
        const md = init(td)[0];
        if (md) {
            nifi.graph?.addNode(md);
        }
    }
    // 更新元素
    const set = async (data: any) => { }
    //
    const del = async (data: any) => { }
    //
    const refresh = async (node: Cell) => { }
    //
    const update = (td: any) => {
        const { revision, id } = td;
        const sd = nifi.cells.get(id);
        nifi.cells.set(td)
        // 获取目标数据和原始数据并比较值的变化，取变化的值的集合
        const props: any = diff(pickData(td, KEYS), pickData(sd, KEYS));
        if (sd && revision.version == sd.revision.version && props == undefined) {
            console.info('=========== 没有发现版本和数据变化 无需更新节点属性 ============', props)
            return false;
        }
        if (props && Object.keys(props).length > 0) {
            nifi.graph?.getCellById(id)?.prop(props);
        }
    }
    //
    const edit = (node: Cell, evt: any = undefined) => {
        node.prop('stopBlur', 1)
        if (evt.target.onblur == null) {
            evt.target.onblur = () => {
                const stop = node.prop('stopBlur');
                if (stop !== 0) {
                    if(stop == 1){
                        node.prop('stopBlur', 0)
                        setTimeout(() => evt.target.focus(),0)
                    }                    
                    return;
                }
                const v = evt.target.value;
                const sd = nifi.cells.get(node)
                if (v != sd.component.label) {
                    const data = { revision: sd.revision, disconnectedNodeAcknowledged: false, component: { id: node.id, label: v } }
                    nifi.cells.setCell(node, data).then(res => {
                        update(res)
                        evt.target.value = '';
                    })
                } else {
                    evt.target.value = '';
                }
                node.prop('stopBlur', -1)
                node.setZIndex(1)
            }
        }
        node.setZIndex(900)
        evt.target.value = node.prop('value') || ''
    }
    const view = (node: Cell) => { }
    //
    const contextmenu = (node: Cell, evt: any) => { 
        node.prop('stopBlur', -1)
        evt.target?.blur();
        const vnode: any = h(ContextmenuElem, { cell:node, nifi })
        nifi.contextmenu.open(evt, vnode)
    }

    return { name, init, add, set, del, refresh, update, edit, view, contextmenu }
}